<?php
class RedisFactory
{
    const CONNECT_TIMEOUT = 1;
	private static $connectors = array();

    public static function create($dsn = null)
    {
		$dsn = trim($dsn);

        if(!$dsn) 
		{
			throw new NICED_ValidationException("no dsn passed in");
		}

        $dsn        = strtolower($dsn);
        $connectors = &self::$connectors;
        
        if(!isset($connectors[$dsn]))
        {
			$redis = self::getRedis($dsn);
            $connectors[$dsn] = $redis;
        }

        return $connectors[$dsn];
    }

	private static function getRedis($dsn)
	{
		$options    = NICED_DBFactory::getDsnSetting($dsn);
        $ip      = isset($options["ip"])      ? $options["ip"] : NULL;
        $port    = isset($options["port"])    ? $options["port"] : NULL;
        $timeout = isset($options["timeout"]) ? $options["timeout"] : self::CONNECT_TIMEOUT;
		
		//@see application/config/dsn.php
		if ('redis' != strtolower($options['type']))
		{
			throw new NICED_ValidationException("dsn type is not redis");
		}

		if (!class_exists('Redis'))
		{
			throw new NICED_NotExistsException('Redis class not exists');
		}

		$redis = new Redis();
        $bool = $redis->connect($ip, $port, $timeout);

        if (!$bool)
        {
            NICED_ALARM("redis_connect_fail");
            $ip      = isset($options["failover_server"]["ip"])      ? $options["ip"] : NULL;
            $port    = isset($options["failover_server"]["port"])    ? $options["port"] : NULL;

            if ($ip)
            {
                NICED_ALARM("redis_server_failover");
                $bool = $redis->connect($ip, $port, $timeout);

                if (!$bool)
                {
                    NICED_ALARM("redis_connect_fail");
                    throw new NICED_Exception("can not connect to redis server", NULL);
                }
            }
        }

		return $redis;
	}
    
	public static function closeAll() 
	{
		$connectors = self::$connectors;
        unset($connectors);
	}

} //end class
register_shutdown_function(array('RedisFactory', 'closeAll'));
